// ============================================================================
// 日志查看器组件
// ============================================================================

import React, { useState, useEffect, useMemo, useCallback } from 'react'
import { 
  FunnelIcon, 
  ArrowDownTrayIcon, 
  TrashIcon,
  MagnifyingGlassIcon,
  ExclamationTriangleIcon,
  InformationCircleIcon,
  ExclamationCircleIcon,
  XCircleIcon
} from '@heroicons/react/24/outline'
import { VirtualList } from './virtual-list'
import { Button, Card, SearchInput, Modal } from './index'
import { logger, LogLevel, LogEntry } from '../../utils/logger'
import { useResponsive } from '../../hooks/use-responsive'

// ============================================================================
// 类型定义
// ============================================================================

interface LogViewerProps {
  height?: number
  showFilters?: boolean
  autoRefresh?: boolean
  refreshInterval?: number
}

interface LogFilters {
  level?: LogLevel
  component?: string
  search?: string
  timeRange?: {
    start: Date
    end: Date
  }
}

// ============================================================================
// 日志级别配置
// ============================================================================

const LOG_LEVEL_CONFIG = {
  [LogLevel.DEBUG]: {
    label: 'DEBUG',
    color: 'text-gray-600 dark:text-gray-400',
    bgColor: 'bg-gray-100 dark:bg-gray-800',
    icon: InformationCircleIcon
  },
  [LogLevel.INFO]: {
    label: 'INFO',
    color: 'text-blue-600 dark:text-blue-400',
    bgColor: 'bg-blue-100 dark:bg-blue-900/20',
    icon: InformationCircleIcon
  },
  [LogLevel.WARN]: {
    label: 'WARN',
    color: 'text-yellow-600 dark:text-yellow-400',
    bgColor: 'bg-yellow-100 dark:bg-yellow-900/20',
    icon: ExclamationTriangleIcon
  },
  [LogLevel.ERROR]: {
    label: 'ERROR',
    color: 'text-red-600 dark:text-red-400',
    bgColor: 'bg-red-100 dark:bg-red-900/20',
    icon: ExclamationCircleIcon
  },
  [LogLevel.FATAL]: {
    label: 'FATAL',
    color: 'text-red-800 dark:text-red-300',
    bgColor: 'bg-red-200 dark:bg-red-900/40',
    icon: XCircleIcon
  }
}

// ============================================================================
// 日志项组件
// ============================================================================

const LogItem = React.memo(({ log, searchTerm }: { log: LogEntry; searchTerm?: string }) => {
  const { isMobile } = useResponsive()
  const config = LOG_LEVEL_CONFIG[log.level]
  const Icon = config.icon

  const highlightText = useCallback((text: string, term?: string) => {
    if (!term) return text
    
    const regex = new RegExp(`(${term})`, 'gi')
    const parts = text.split(regex)
    
    return parts.map((part, index) => 
      regex.test(part) ? (
        <mark key={index} className="bg-yellow-200 dark:bg-yellow-800 px-1 rounded">
          {part}
        </mark>
      ) : part
    )
  }, [])

  const formatTimestamp = (timestamp: Date) => {
    return timestamp.toLocaleString('zh-CN', {
      hour12: false,
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      fractionalSecondDigits: 3
    })
  }

  return (
    <div className={`p-3 border-l-4 ${config.bgColor} border-l-current ${config.color}`}>
      <div className="flex items-start space-x-2">
        <Icon className="w-4 h-4 mt-0.5 flex-shrink-0" />
        
        <div className="flex-1 min-w-0">
          {/* 头部信息 */}
          <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-1">
            <div className="flex items-center space-x-2">
              <span className={`text-xs font-mono px-2 py-1 rounded ${config.bgColor} ${config.color}`}>
                {config.label}
              </span>
              {log.component && (
                <span className="text-xs text-gray-500 dark:text-gray-400 font-mono">
                  [{log.component}]
                </span>
              )}
            </div>
            
            <span className="text-xs text-gray-500 dark:text-gray-400 font-mono">
              {formatTimestamp(log.timestamp)}
            </span>
          </div>

          {/* 消息内容 */}
          <div className="text-sm text-gray-800 dark:text-gray-200 mb-2">
            {highlightText(log.message, searchTerm)}
          </div>

          {/* 数据内容 */}
          {log.data && (
            <details className="text-xs">
              <summary className="cursor-pointer text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200">
                数据详情
              </summary>
              <pre className="mt-2 p-2 bg-gray-100 dark:bg-gray-700 rounded text-gray-700 dark:text-gray-300 overflow-auto">
                {typeof log.data === 'string' ? log.data : JSON.stringify(log.data, null, 2)}
              </pre>
            </details>
          )}

          {/* 错误堆栈 */}
          {log.stack && (
            <details className="text-xs mt-2">
              <summary className="cursor-pointer text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200">
                错误堆栈
              </summary>
              <pre className="mt-2 p-2 bg-gray-100 dark:bg-gray-700 rounded text-gray-700 dark:text-gray-300 overflow-auto">
                {log.stack}
              </pre>
            </details>
          )}
        </div>
      </div>
    </div>
  )
})

LogItem.displayName = 'LogItem'

// ============================================================================
// 主日志查看器组件
// ============================================================================

export function LogViewer({ 
  height = 600, 
  showFilters = true, 
  autoRefresh = true,
  refreshInterval = 1000 
}: LogViewerProps) {
  const { isMobile } = useResponsive()
  
  const [logs, setLogs] = useState<LogEntry[]>([])
  const [filters, setFilters] = useState<LogFilters>({})
  const [showFilterModal, setShowFilterModal] = useState(false)
  const [stats, setStats] = useState<{ total: number; byLevel: Record<string, number> }>({ total: 0, byLevel: {} })

  // 获取日志数据
  const refreshLogs = useCallback(() => {
    const allLogs = logger.getLogs()
    const logStats = logger.getStats()
    
    setLogs(allLogs)
    setStats(logStats)
  }, [])

  // 自动刷新
  useEffect(() => {
    refreshLogs()
    
    if (autoRefresh) {
      const interval = setInterval(refreshLogs, refreshInterval)
      return () => clearInterval(interval)
    }
  }, [refreshLogs, autoRefresh, refreshInterval])

  // 过滤日志
  const filteredLogs = useMemo(() => {
    return logs.filter(log => {
      // 级别过滤
      if (filters.level !== undefined && log.level < filters.level) {
        return false
      }

      // 组件过滤
      if (filters.component && log.component !== filters.component) {
        return false
      }

      // 搜索过滤
      if (filters.search) {
        const searchTerm = filters.search.toLowerCase()
        const searchableText = [
          log.message,
          log.component,
          typeof log.data === 'string' ? log.data : JSON.stringify(log.data)
        ].join(' ').toLowerCase()
        
        if (!searchableText.includes(searchTerm)) {
          return false
        }
      }

      // 时间范围过滤
      if (filters.timeRange) {
        const logTime = log.timestamp.getTime()
        const startTime = filters.timeRange.start.getTime()
        const endTime = filters.timeRange.end.getTime()
        
        if (logTime < startTime || logTime > endTime) {
          return false
        }
      }

      return true
    })
  }, [logs, filters])

  // 获取唯一组件列表
  const components = useMemo(() => {
    const componentSet = new Set<string>()
    logs.forEach(log => {
      if (log.component) {
        componentSet.add(log.component)
      }
    })
    return Array.from(componentSet).sort()
  }, [logs])

  // 处理搜索
  const handleSearch = useCallback((search: string) => {
    setFilters(prev => ({ ...prev, search }))
  }, [])

  // 处理级别过滤
  const handleLevelFilter = useCallback((level?: LogLevel) => {
    setFilters(prev => ({ ...prev, level }))
  }, [])

  // 处理组件过滤
  const handleComponentFilter = useCallback((component?: string) => {
    setFilters(prev => ({ ...prev, component }))
  }, [])

  // 清空日志
  const handleClearLogs = useCallback(() => {
    if (confirm('确定要清空所有日志吗？')) {
      logger.clearLogs()
      refreshLogs()
    }
  }, [refreshLogs])

  // 导出日志
  const handleExportLogs = useCallback(() => {
    const logText = filteredLogs.map(log => {
      const timestamp = log.timestamp.toISOString()
      const level = LOG_LEVEL_CONFIG[log.level].label
      const component = log.component ? `[${log.component}]` : ''
      const data = log.data ? `\nData: ${JSON.stringify(log.data, null, 2)}` : ''
      const stack = log.stack ? `\nStack: ${log.stack}` : ''
      
      return `${timestamp} ${level} ${component} ${log.message}${data}${stack}`
    }).join('\n\n')

    const blob = new Blob([logText], { type: 'text/plain' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `logs_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.txt`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  }, [filteredLogs])

  // 渲染虚拟列表项
  const renderLogItem = useCallback((log: LogEntry, index: number) => (
    <LogItem key={`${log.timestamp.getTime()}-${index}`} log={log} searchTerm={filters.search} />
  ), [filters.search])

  return (
    <div className="space-y-4">
      {/* 统计信息 */}
      <div className="grid grid-cols-2 sm:grid-cols-5 gap-2">
        <Card className="p-3 text-center">
          <div className="text-lg font-bold text-gray-900 dark:text-white">{stats.total}</div>
          <div className="text-xs text-gray-500 dark:text-gray-400">总计</div>
        </Card>
        
        {Object.entries(LOG_LEVEL_CONFIG).map(([level, config]) => {
          const count = stats.byLevel[config.label] || 0
          return (
            <Card key={level} className={`p-3 text-center ${config.bgColor}`}>
              <div className={`text-lg font-bold ${config.color}`}>{count}</div>
              <div className={`text-xs ${config.color}`}>{config.label}</div>
            </Card>
          )
        })}
      </div>

      {/* 工具栏 */}
      {showFilters && (
        <Card className="p-4">
          <div className="flex flex-col lg:flex-row lg:items-center lg:justify-between space-y-4 lg:space-y-0">
            {/* 搜索和过滤 */}
            <div className="flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-2 flex-1">
              <SearchInput
                placeholder="搜索日志..."
                onSearch={handleSearch}
                className="flex-1"
              />
              
              <div className="flex space-x-2">
                <select
                  value={filters.level ?? ''}
                  onChange={(e) => handleLevelFilter(e.target.value ? Number(e.target.value) : undefined)}
                  className="input text-sm"
                >
                  <option value="">所有级别</option>
                  {Object.entries(LOG_LEVEL_CONFIG).map(([level, config]) => (
                    <option key={level} value={level}>{config.label}</option>
                  ))}
                </select>
                
                <select
                  value={filters.component ?? ''}
                  onChange={(e) => handleComponentFilter(e.target.value || undefined)}
                  className="input text-sm"
                >
                  <option value="">所有组件</option>
                  {components.map(component => (
                    <option key={component} value={component}>{component}</option>
                  ))}
                </select>
              </div>
            </div>

            {/* 操作按钮 */}
            <div className="flex space-x-2">
              <Button
                variant="outline"
                size="sm"
                onClick={handleExportLogs}
                icon={<ArrowDownTrayIcon className="w-4 h-4" />}
              >
                {!isMobile && '导出'}
              </Button>
              
              <Button
                variant="outline"
                size="sm"
                onClick={handleClearLogs}
                icon={<TrashIcon className="w-4 h-4" />}
              >
                {!isMobile && '清空'}
              </Button>
            </div>
          </div>
        </Card>
      )}

      {/* 日志列表 */}
      <Card>
        {filteredLogs.length === 0 ? (
          <div className="text-center py-12">
            <InformationCircleIcon className="w-12 h-12 text-gray-400 mx-auto mb-4" />
            <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
              暂无日志
            </h3>
            <p className="text-gray-500 dark:text-gray-400">
              {logs.length === 0 ? '还没有任何日志记录' : '没有符合筛选条件的日志'}
            </p>
          </div>
        ) : (
          <VirtualList
            items={filteredLogs}
            itemHeight={120}
            renderItem={renderLogItem}
            height={height}
            className="border-0"
          />
        )}
      </Card>
    </div>
  )
}
